/**
 * @file      ac_tlm_router.h
 * @author    Bruno de Carvalho Albertini
 * 
 * @author    The ArchC Team
 *            http://www.archc.org/
 *
 *            Computer Systems Laboratory (LSC)
 *            IC-UNICAMP
 *            http://www.lsc.ic.unicamp.br/
 *
 * @author    Grupo 06
 * 
 * @version   0.1
 * @date      Sat Mai  2 15:44:55 BRT 2009
 * 
 * @brief     Defines an ac_tlm router that works like a simplyfied
 *            bus structure.
 * 
 * @attention Copyright (C) 2002-2009 --- The ArchC Team
 * 
 *   This library is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later version.
 * 
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *   Lesser General Public License for more details.
 * 
 * 
 */

//////////////////////////////////////////////////////////////////////////////

#ifndef AC_TLM_ROUTER_H_
#define AC_TLM_ROUTER_H_

//////////////////////////////////////////////////////////////////////////////

// Standard includes
// SystemC includes
#include <systemc>
// ArchC includes
#include "ac_tlm_protocol.H"
#include "ac_tlm_port.H"
//#include  "ac_memport.H"

#define ADDR_MEM		  0x0000000
#define ADDR_VIDEO		0x1000000
#define ADDR_KEYBOARD 0x2000000
#define ADDR_CARD		  0x3000000
#define ADDR_COUNTER  0x4000000
#define ADDR_END		  0x5000000

//////////////////////////////////////////////////////////////////////////////

// using statements
using tlm::tlm_transport_if;

//////////////////////////////////////////////////////////////////////////////

/// Namespace to isolate router from ArchC
namespace user
{

/// A TLM router
class ac_tlm_router :
  public sc_module,
  public ac_tlm_transport_if // Using ArchC TLM protocol
{
public:

  /// Exposed port with ArchC interface
  sc_export< ac_tlm_transport_if > target_export;
  sc_export< ac_tlm_transport_if > target2_export;
  ac_tlm_port mem_port;
  ac_tlm_port counter_port;
  ac_tlm_port teclado_port;
  ac_tlm_port video_port;
  ac_tlm_port card_port;
  
  /**
   * Implementation of TLM transport method that
   * handle packets of the protocol doing apropriate actions.
   * This method must be implemented (required by SystemC TLM).
   * @param request is a received request packet
   * @return A response packet to be send
  */
  ac_tlm_rsp transport( const ac_tlm_req &request ) {

    ac_tlm_req req = request;
    ac_tlm_rsp response;

    if( (request.addr >= ADDR_MEM) && (request.addr < ADDR_VIDEO) ) {
       req.addr -= ADDR_MEM;
       response = mem_port->transport(req);
    }
    else if ( (request.addr >= ADDR_VIDEO) && (request.addr < ADDR_KEYBOARD) ) {
       req.addr -= ADDR_VIDEO;
       response = video_port->transport(req);
    }
    else if ( (request.addr >= ADDR_KEYBOARD) && (request.addr < ADDR_CARD) ) {
       req.addr -= ADDR_KEYBOARD;
       response = teclado_port->transport(req);
    }
    else if ( (request.addr >= ADDR_CARD) && (request.addr < ADDR_COUNTER) ) {
       req.addr -= ADDR_CARD;
       response = card_port->transport(req);
    }
    else if ( (request.addr >= ADDR_COUNTER) && (request.addr < ADDR_END) ) {
       req.addr -= ADDR_COUNTER;
       response = counter_port->transport(req);
    }
    else {
       response.status = ERROR;
    }

    return response;
  }


  /** 
   * Default constructor.
   */
  ac_tlm_router( sc_module_name module_name );

  /** 
   * Default destructor.
   */
  ~ac_tlm_router();

};

};

#endif //AC_TLM_ROUTER_H_
